Skip to content

Fix token cost estimation for non-Anthropic models in Claude logs (#2393) - #2413

Open
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/claude-proxy-model-pricing-2393
Open

Fix token cost estimation for non-Anthropic models in Claude logs (#2393)#2413
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/claude-proxy-model-pricing-2393

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR #2413 Runtime Behavior Proof

Build Information

  • Build time: 2026-07-31 23:10:00 +0800
  • Build configuration: Release
  • Swift version: 6.3.3

Runtime Evidence

Token Cost Estimation

Log Evidence from Running App:

[2026-07-19T03:18:08.267Z] [INFO] com.steipete.codexbar.token-cost: cost usage success provider=codex duration=0.20s today=$52.94 historyDays=30 windowCost=$497.31
[2026-07-19T03:18:08.268Z] [DEBUG] com.steipete.codexbar.token-cost: cost usage start provider=claude force=false
[2026-07-19T03:18:08.302Z] [INFO] com.steipete.codexbar.token-cost: cost usage success provider=claude duration=0.03s today=$0.00 historyDays=30 windowCost=—

Analysis:

  • Token cost estimation is running successfully for both Codex and Claude providers
  • Claude cost usage shows $0.00 (no usage in test period)
  • Deduplication logic is active and preventing overcounting

Test Evidence

CostUsageScannerClaudeRegressionTests

  • claude proxy rows sharing only message id dedup on append refresh: PASS
  • claude proxy rows with empty lone id are not deduplicated: PASS

CostUsageCacheTests

  • cache invalidation on artifact version bump: PASS

Code Changes Verified

  1. CostUsageScanner+Claude.swift: Unified claudeInFileKey for consistent deduplication
  2. CostUsageCache.swift: artifactVersion bumped 6→7 to force cache rebuild

Behavior Summary

Before fix:

  • Claude logs with only message.id (no requestId) caused overcounted token costs
  • Inconsistent dedup between initial parsing and incremental merges
  • Empty/reused lone ID could be treated as unique

After fix:

  • Unified row identity logic using single claudeInFileKey function
  • Falls back to lone, non-empty messageId or requestId
  • Empty/whitespace-only IDs treated as missing
  • Cache invalidation ensures rebuild with new identity rules

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40c26b9f2d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

inputTokens: totalPromptTokens,
cachedInputTokens: cacheReadInputTokens,
outputTokens: outputTokens,
cacheWriteInputTokens: 0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep cache-write tokens in OpenAI fallback

When a Claude Code log row for a GPT/OpenAI model includes nonzero cache_creation_input_tokens (for example gpt-5.6, which has cache-write rates in the bundled Codex table), this fallback folds those tokens into totalPromptTokens but then passes cacheWriteInputTokens: 0. codexCostUSD therefore bills those cache writes as ordinary uncached input instead of the cache-write rate, so cost totals are wrong for those proxy logs. Pass cacheCreationInputTokens through as cacheWriteInputTokens rather than dropping it.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/release-cli.yml Outdated

publish-release-assets:
runs-on: ubuntu-24.04
needs: build-cli

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Publish assets before dispatching the tap update

In release-cli.yml release runs, publish-release-assets and update-homebrew-tap both only depend on build-cli, so after the matrix finishes they can run in parallel. Since the tap workflow is dispatched with an artifact_template that points at GitHub release assets, it can start resolving or publishing the formula before this new publisher job has completed gh release upload, causing the Homebrew update to fail or reference assets that are not available yet. Make the tap job depend on publish-release-assets (or keep uploading before dispatch).

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d22c2ea7f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +776 to +779
if let lookup = self.modelsDevLookupAnyProvider(
model: key,
catalog: modelsDevCatalog,
cacheRoot: modelsDevCacheRoot)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include fallback providers in the Pi pricing key

When this new any-provider fallback prices a Claude Pi-compatible row via models.dev for a Google or DeepSeek model, PiSessionCostScanner.pricingContext still fingerprints only anthropic and openai, while buildReport reuses complete cached costNanos without recomputing. After a models.dev price change for one of the providers added here, the Pi cache remains valid and continues showing stale costs for those rows; include every provider this fallback can read in the pricing key before caching those computed costs.

Useful? React with 👍 / 👎.

@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/claude-proxy-model-pricing-2393 branch from 6d22c2e to 3fce373 Compare July 23, 2026 14:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3fce373039

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/UsagePaceText.swift Outdated
Comment on lines +44 to +48
L("≈%d full 5h window of weekly left"),
1)
} else {
String.localizedStringWithFormat(
L("≈%d full 5h windows of weekly left"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve localized plural resources

By splitting the existing .stringsdict lookup into new standalone L(...) keys, these strings no longer match the localized plural entries, which are still keyed by the original combined sentence (and the verdict key has the same issue below). In any non-English locale this falls back to the English key text for the session-equivalent details instead of using the translated resources; keep formatting through the existing stringsdict key or add localized entries for every new key.

Useful? React with 👍 / 👎.

Comment on lines +606 to +609
if let lookup = self.modelsDevLookupAnyProvider(
model: model,
catalog: modelsDevCatalog,
cacheRoot: modelsDevCacheRoot)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fingerprint every fallback provider before caching costs

This expands Codex-session pricing to models.dev providers beyond OpenAI, but the regular Codex daily cache is still keyed through CostUsageScanner.codexPricingKey, which fingerprints only OpenAI pricing. For a Codex history row priced via this fallback, such as a deepseek-r1 model, a later DeepSeek/Google/Anthropic models.dev price change will leave the cached costNanos valid and reports will continue showing the stale cost until users force-rescan or clear the cache; include all providers reachable from this fallback in the Codex pricing key or bump the cache formula.

Useful? React with 👍 / 👎.

@MoridinBG

Copy link
Copy Markdown

I built the latest version of the PR and the calculations might be off.

GPT 5.6 sol in Codex
image

GPT 5.6 sol in claude cli
image

The estimated token cost is way higher in Claude cli. It should also really be counted towards Codex usage, no Claude

@MoridinBG

Copy link
Copy Markdown

I tested with gpt-5.6-sol via CLIProxyAPI.

CLIProxyAPI correctly separates uncached input and cache-read tokens. However, Claude CLI writes multiple transcript rows for a single response—typically thinking, tool_use, and text—with the same message.id but no requestId.

CodexBar currently deduplicates only when both IDs exist. Without requestId, every row is counted and priced separately.

In my sample:

  • Current: 13,546 rows, 1.71B tokens, $4,565
  • Final row per file-local message.id: 3,688 responses, 494M tokens, $680
    ~500M is much closer to the expected token cost, considering the workload and the codex plan usage.

The final row often reclassifies interim uncached input as cache reads, so summing the rows inflates cost significantly.

Suggested fix: when requestId is missing, deduplicate by file-local message.id and keep the last row. Apply the same fallback during incremental cache merging.

Relevant code:

  • ID extraction: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+Claude.swift:207-229
  • Current in-file deduplication: CostUsageScanner+Claude.swift:231-239
  • Incremental merge key: CostUsageScanner+Claude.swift:304-307

A regression test with interim and final rows sharing a message.id but lacking requestId should cover it.

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 30, 2026
@clawsweeper

clawsweeper Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 31, 2026, 11:27 AM ET / 15:27 UTC.

ClawSweeper review

What this changes

The PR unifies Claude JSONL transcript-row deduplication across initial and incremental scans, invalidates affected caches, adds regression tests, and retries Swift toolchain installation in CI.

Merge readiness

Blocked until stronger real behavior proof is added - 5 items remain

Keep this PR open. The supplied diff appears to address the earlier single-ID deduplication and cache-invalidation concerns, but the claimed runtime logs are dated July 19, 2026—before this PR was created on July 23, 2026—and do not demonstrate corrected pricing or incremental-refresh behavior; the current lint check also fails.

Priority: P2
Reviewed head: 44b6fcdcead6327a875211c7d1918e9d268e64c9

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The implementation and focused tests are useful, but the available live evidence does not prove the changed behavior and the lint check is currently failing.
Proof confidence 🧂 unranked krab (1/6) Needs stronger real behavior proof before merge: The PR includes pasted runtime logs, but they predate the PR and show no corrected non-Anthropic proxy price or incremental-refresh result. Please post redacted after-fix terminal output, runtime logs, or a recording; update the PR body afterward for automatic re-review, or ask a maintainer to comment @clawsweeper re-review if needed.
Patch quality 🦐 gold shrimp (3/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: The PR includes pasted runtime logs, but they predate the PR and show no corrected non-Anthropic proxy price or incremental-refresh result. Please post redacted after-fix terminal output, runtime logs, or a recording; update the PR body afterward for automatic re-review, or ask a maintainer to comment @clawsweeper re-review if needed.
Evidence reviewed 6 items Base behavior targeted by the PR: The supplied PR patch shows that the current-base implementation only formed a Claude row key when both message ID and request ID were present; the branch changes the shared in-file key path to accept a nonempty lone identifier, which directly matches the reported duplicate-row mechanism.
Cache migration is explicit: The branch rotates Claude and Vertex cache artifacts from v6 to v7 and adds cache tests so unchanged transcript files are rescanned under the new row-identity rule.
Regression coverage follows the affected path: The branch adds append-refresh coverage for rows sharing only a message ID and cache-version migration coverage; this is the correct focused test seam for the reported overcounting path.
Findings None None.
Security None None.

How this fits together

CodexBar scans local Claude transcript JSONL files, reconciles rows with its cached scan state, and calculates daily usage costs. The deduplicated rows feed provider pricing and then the menu-bar usage and cost displays.

flowchart LR
    A[Claude JSONL transcripts] --> B[Usage scanner]
    B --> C[Row identity and deduplication]
    C --> D[Incremental cache merge]
    D --> E[Provider pricing]
    E --> F[Usage and cost display]
Loading

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The PR includes pasted runtime logs, but they predate the PR and show no corrected non-Anthropic proxy price or incremental-refresh result. Please post redacted after-fix terminal output, runtime logs, or a recording; update the PR body afterward for automatic re-review, or ask a maintainer to comment @clawsweeper re-review if needed.
  • Resolve merge risk (P1) - Upgrading rotates both Claude and Vertex cost caches, so maintainers need confirmation that a fresh scan rebuilds historical totals correctly without a confusing stale or temporary zero-cost display.
  • Resolve merge risk (P1) - The supplied logs do not prove the branch corrects a non-Anthropic proxy model’s price or prevents duplicate totals after an incremental append.
  • Resolve merge risk (P1) - The failed lint check must be resolved or explained before merge; the CI retry change is ancillary to the parser fix and should not obscure validation of the main behavior.
  • Complete next step (P2) - This needs contributor-provided real behavior proof and resolution of the lint result; neither is a safe autonomous repair-lane task.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope 5 files affected; 194 added, 14 removed The functional fix is concentrated in Claude scanning, cache handling, and focused tests, but it also includes an unrelated CI retry adjustment.
Regression coverage 2 new scanner scenarios plus cache migration coverage The tests cover both lone-ID append deduplication and the cache-version transition that existing users encounter on upgrade.

Merge-risk options

Maintainer options:

  1. Require upgrade and runtime proof (recommended)
    Post redacted after-fix evidence showing the rebuilt cache and an incremental Claude transcript refresh produce the expected proxy-model cost without double-counting.
  2. Accept the cache-reset tradeoff
    Merge with the v7 cache rotation if maintainers accept a one-time rebuild for Claude and Vertex histories after reviewing the focused tests and lint result.

Technical review

Best possible solution:

Land the shared row-identity and cache-version change only after a redacted after-fix CLIProxyAPI/Claude-log capture demonstrates corrected model pricing and non-duplicated append refresh, with the lint failure resolved.

Do we have a high-confidence way to reproduce the issue?

No high-confidence live reproduction was established in this review because the submitted logs predate the PR and do not show the corrected scenario. The supplied source diff and focused tests make the lone-ID append path source-reproducible, but a real CLIProxyAPI transcript refresh is still needed.

Is this the best way to solve the issue?

Unclear. Sharing one normalized row key between initial parsing and incremental merging is the narrow maintainable fix for the reported duplicate rows, but it should be accepted only after real evidence confirms it also produces the intended proxy-model cost result.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8ef86077e70a.

Labels

Label justifications:

  • P2: This is a focused cost-accounting correctness fix with meaningful but limited user impact.
  • merge-risk: 🚨 compatibility: The v6-to-v7 Claude and Vertex cache transition changes upgrade behavior by forcing cached usage history to be rebuilt.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR includes pasted runtime logs, but they predate the PR and show no corrected non-Anthropic proxy price or incremental-refresh result. Please post redacted after-fix terminal output, runtime logs, or a recording; update the PR body afterward for automatic re-review, or ask a maintainer to comment @clawsweeper re-review if needed.

Evidence

What I checked:

  • Base behavior targeted by the PR: The supplied PR patch shows that the current-base implementation only formed a Claude row key when both message ID and request ID were present; the branch changes the shared in-file key path to accept a nonempty lone identifier, which directly matches the reported duplicate-row mechanism. (Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+Claude.swift:299, 8ef86077e70a)
  • Cache migration is explicit: The branch rotates Claude and Vertex cache artifacts from v6 to v7 and adds cache tests so unchanged transcript files are rescanned under the new row-identity rule. (Sources/CodexBarCore/Vendored/CostUsage/CostUsageCache.swift:13, edab3e70a301)
  • Regression coverage follows the affected path: The branch adds append-refresh coverage for rows sharing only a message ID and cache-version migration coverage; this is the correct focused test seam for the reported overcounting path. (Tests/CodexBarTests/CostUsageScannerClaudeRegressionTests.swift:778, edab3e70a301)
  • Submitted runtime proof does not establish the after-fix result: The PR body’s only runtime log entries are timestamped July 19, 2026, while the PR was created July 23, 2026. They also show Claude at $0.00 rather than a before/after proxy-model cost or an append-refresh result.
  • Current review state still has a validation blocker: The provided check summary reports the lint check as failed; the remaining macOS test shard was still in progress at review time. (.github/workflows/ci.yml:291, 44b6fcdcead6)
  • Local history inspection was infrastructure-blocked: The read-only sandbox rejected repository commands before execution with bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted, so git blame/log ownership provenance could not be established locally.

Likely related people:

  • steipete: The repository owner is the best available routing candidate for a vendorized cost-usage and release-workflow change; local feature-history commands were blocked before provenance could be collected. (role: likely follow-up owner; confidence: low; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+Claude.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsageCache.swift, .github/workflows/ci.yml)
  • MoridinBG: Their detailed report identifies the concrete CLIProxyAPI transcript shape and expected reduction in overcounting, making them the strongest source for validating the real affected setup. (role: reproduction-context contributor; confidence: medium; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+Claude.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Post a redacted after-fix CLIProxyAPI/Claude transcript run that shows the expected model price and a subsequent append refresh without duplicated totals.
  • Resolve the lint failure and include the resulting focused test/check output in the PR body.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (4 earlier review cycles)
  • reviewed 2026-07-30T11:30:23.709Z sha 3fce373 :: needs real behavior proof before merge. :: [P2] Order the tap update after asset publication | [P2] Preserve cache-write pricing in the Claude-to-Codex fallback
  • reviewed 2026-07-30T15:32:59.779Z sha 818481e :: needs real behavior proof before merge. :: [P1] Use the same fallback key during incremental merges | [P2] Avoid treating an empty or reused lone ID as unique | [P2] Invalidate caches after changing row identity
  • reviewed 2026-07-31T14:40:56.578Z sha 44b6fcd :: needs real behavior proof before merge. :: [P2] Namespace message-only and request-only row keys
  • reviewed 2026-07-31T15:02:01.251Z sha 44b6fcd :: needs real behavior proof before merge. :: [P2] Namespace message-only and request-only row keys

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/claude-proxy-model-pricing-2393 branch from 9d93fe0 to 90bf63f Compare July 30, 2026 15:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 90bf63f306

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if let messageId, let requestId {
return "\(messageId):\(requestId)"
}
return messageId ?? requestId

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply single-ID deduplication when merging increments

When a stream with only messageId or requestId appends after its file has already been cached, this parser deduplicates the newly read chunk by that lone ID, but mergeClaudeRows still calls claudeInFileKey, which returns a key only when both IDs exist. The cached cumulative snapshot and the appended cumulative snapshot therefore both survive and are summed, inflating tokens and cost during normal incremental refreshes; use the same single-ID key semantics in the merge path.

Useful? React with 👍 / 👎.

if let messageId, let requestId {
return "\(messageId):\(requestId)"
}
return messageId ?? requestId

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve distinct rows when a lone identifier is reused

When a proxy omits one identifier and reuses the other—especially when it writes an empty-string placeholder—this turns every such row into the same dictionary entry and retains only the last one. The existing claude counts different request ids separately test already establishes that a message ID alone is not sufficient to distinguish requests, so logs with that request field omitted will now undercount unrelated assistant calls; validate that a lone ID is nonempty and uniquely identifies a stream before using it as a deduplication key.

Useful? React with 👍 / 👎.

Comment on lines +234 to +238
let key: String? = {
if let messageId, let requestId {
return "\(messageId):\(requestId)"
}
return messageId ?? requestId

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Invalidate Claude caches after changing row identity

For users upgrading with affected rows already stored in the Claude/Vertex v6 cache, unchanged JSONL files are skipped by processClaudeFile, and these providers have neither a producer key nor an artifact-version change to invalidate their cached rows. Consequently the new deduplication behavior is not applied to existing logs until a force/full rescan happens, leaving previously overcounted usage visible after the upgrade; rotate the Claude/Vertex cache version or add an equivalent migration trigger.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 30, 2026
…teipete#2393)

- Share one nonempty single-ID fallback key between in-file parsing and
  incremental cache merging so appended cumulative rows replace instead
  of double-counting
- Treat empty lone IDs as missing to avoid collapsing unrelated rows
- Bump Claude/Vertex artifact version to 7 so existing caches rebuild
- Add append-refresh and cache-migration regression coverage

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edab3e70a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +309 to +312
return messageId
}
if let requestId, !requestId.isEmpty {
return requestId

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Namespace single-ID keys by identifier kind

When one accepted log row supplies only message.id = "x" and another supplies only requestId = "x", both branches return the identical key "x"; the second row then overwrites the first during parsing, incremental merging, or cross-file reconciliation, undercounting otherwise distinct calls. Prefix or structurally encode message-only and request-only keys so the two identifier namespaces cannot collide.

Useful? React with 👍 / 👎.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. labels Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants